package com.dream.banana.dubbo.echo.impl;

import com.alibaba.dubbo.rpc.RpcException;
import com.alibaba.dubbo.rpc.service.EchoService;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import com.dream.banana.dubbo.echo.IDubboReferenceMonitorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.Ordered;
/**
 * 躲了一辈子雨，雨会不会很难过。
 * </p>
 * Created by zhumenglong on 2017/5/28.
 */
public class DubboReferenceMonitorServiceImpl implements IDubboReferenceMonitorService, BeanPostProcessor, ApplicationContextAware, Ordered {
    private final Logger logger = LoggerFactory.getLogger(DubboReferenceMonitorServiceImpl.class);
    private static final String $ECHO_MESSAGE = "message_ok";
    private static final String REFERENCE_BEANNAME_PREFIX = "reference.";
    private final Set<String> dubboReferenceBeanMap = new LinkedHashSet();
    private ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.startsWith("reference.")) {
            this.dubboReferenceBeanMap.add(beanName);
        }

        return bean;
    }

    public int getReferenceCount() {
        return this.dubboReferenceBeanMap.size();
    }

    public Set<String> getAllReferenceNames() {
        return Collections.unmodifiableSet(this.dubboReferenceBeanMap);
    }

    public Set<ReferenceStatusMonitor> checkAllDubboReferences() {
        LinkedHashSet checkResult = new LinkedHashSet();
        this.dubboReferenceBeanMap.stream().forEach((beanName) -> {
            EchoService echoService = (EchoService) this.applicationContext.getBean(beanName);
            ReferenceStatusMonitor.RefStatusEnum status = ReferenceStatusMonitor.RefStatusEnum.DISABLED;

            try {
                String rpce = echoService.$echo("message_ok").toString();
                if ("message_ok".equals(rpce)) {
                    status = ReferenceStatusMonitor.RefStatusEnum.NORMAL;
                }
            } catch (RpcException arg5) {
                this.logger.error("dubbo服务[" + beanName + "]异常,异常信息:[" + arg5.getMessage() + "]", arg5);
            }

            checkResult.add(new ReferenceStatusMonitor(beanName, status));
        });
        return checkResult;
    }

    public int getOrder() {
        return Integer.MAX_VALUE;
    }
}
